package com.bj58.mis.apm.server.logreceiver.service.impl;

import com.bj58.mis.apm.server.logreceiver.model.ApmClient;
import com.bj58.mis.apm.server.logreceiver.model.ApmPropertySetting;
import com.bj58.mis.apm.server.logreceiver.repository.ApmClientRepository;
import com.bj58.mis.apm.server.logreceiver.repository.PropertiesRepository;
import com.bj58.mis.apm.server.logreceiver.service.PropertiesService;
import com.bj58.mis.apm.server.logreceiver.vo.ApmClientForWeb;
import com.bj58.mis.apm.server.logreceiver.vo.ApmPropertyForClient;
import com.bj58.mis.apm.server.logreceiver.vo.ApmPropertyForWeb;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: wangxw
 * @Date: 2018/7/26 14:55
 */
@Service
public class PropertiesServiceImpl implements PropertiesService {
    @Resource
    private PropertiesRepository propertiesRepository;
    @Resource
    private ApmClientRepository clientRepository;

    @Override
    public List<ApmPropertyForClient> queryProperties(String appName, String hostName) {
        updateRequestTime(appName, hostName);
        List<ApmPropertySetting> list = propertiesRepository.queryByAppNameAndHostName(appName, hostName);
        List<ApmPropertyForClient> rlist = new ArrayList<>();
        for(ApmPropertySetting setting : list){
            ApmPropertyForClient p = new ApmPropertyForClient();
            BeanUtils.copyProperties(setting, p);
            rlist.add(p);
        }
        return rlist;
    }

    @Transactional
    protected void updateRequestTime(String appName, String hostName) {
        ApmClient client = clientRepository.getByAppNameAndHostName(appName, hostName);
        if(client != null){
            client.setLastRequest(new Date());
            clientRepository.save(client);
        }
    }

    @Override
    @Transactional
    public void saveProperties(List<Map<String, String>> propList) {
        String appName = propList.get(0).get("appName");
        String hostName = propList.get(0).get("hostName");
        if(StringUtils.isNotEmpty(appName) && StringUtils.isNotEmpty(hostName)) {
            ApmClient client = clientRepository.getByAppNameAndHostName(appName, hostName);
            if (client == null) {
                client = new ApmClient();
                client.setAppName(appName);
                client.setHostName(hostName);
                client.setCreateTime(new Date());
                client.setLastRequest(client.getCreateTime());
                clientRepository.save(client);
            }
        }

        propList.forEach(map -> {
            String app = map.get("appName");
            String host = map.get("hostName");
            String property = map.get("property");
            String value = map.get("value");
            if(StringUtils.isNotEmpty(app) && StringUtils.isNotEmpty(host)
                    && StringUtils.isNotEmpty(property) && StringUtils.isNotEmpty(value)){
                ApmPropertySetting setting = propertiesRepository.getByAppNameAndHostNameAndProperty(appName, hostName, property);
                if(setting == null){
                    setting = new ApmPropertySetting();
                    setting.setAppName(appName);
                    setting.setHostName(hostName);
                    setting.setProperty(property);
                    setting.setDefaultValue(value);
                    setting.setSetValue(value);
                    setting.setModified(new Date());
                    propertiesRepository.save(setting);
                }
            }
        });
    }

    @Override
    public List<ApmClientForWeb> queryClient() {
        List<ApmClient> list = clientRepository.findAll();
        Date now = new Date();
        List<ApmClientForWeb> wlist = new ArrayList<>();
        for(ApmClient client : list){
            ApmClientForWeb c = new ApmClientForWeb();
            BeanUtils.copyProperties(client, c);
            c.setStatus(now.getTime() - client.getLastRequest().getTime() > 10*60*1000 ? 0 : 1);
            wlist.add(c);
        }
        return wlist;
    }

    @Override
    public List<ApmPropertyForWeb> querySettings(String appName, String hostName) {
        List<ApmPropertySetting> list = propertiesRepository.queryByAppNameAndHostName(appName, hostName);
        List<ApmPropertyForWeb> wlist = new ArrayList<>();
        Map<String, ApmPropertyForWeb> map = new HashMap<>();
        for(ApmPropertySetting setting : list){
            if(!setting.getProperty().startsWith("collector")){
                continue;
            }
            String collector = setting.getProperty().substring(setting.getProperty().indexOf(".") + 1, setting.getProperty().lastIndexOf("."));
            String key = setting.getAppName()+"-"+setting.getHostName()+"-"+collector;
            ApmPropertyForWeb p = map.get(key);
            if(p == null){
                p = new ApmPropertyForWeb();
                BeanUtils.copyProperties(setting, p);
                p.setCollector(collector);
                map.put(key, p);
                wlist.add(p);
            }
            if(setting.getProperty().endsWith("enable")){
                p.setEnable(setting.getSetValue());
            }else if(setting.getProperty().endsWith("period")){
                p.setPeriod(setting.getSetValue());
            }
        }
        return wlist;
    }

    @Override
    public void save(List<ApmPropertyForWeb> list) {
        final Date date = new Date();
        List<ApmPropertySetting> settings = propertiesRepository.queryByAppNameAndHostName(list.get(0).getAppName(), list.get(0).getHostName());
        Map<String, ApmPropertySetting> temp = new HashMap<>();
        settings.forEach(s -> {
            temp.put(s.getProperty(), s);
        });
        list.forEach(p -> {
            ApmPropertySetting enable = temp.get("collector."+p.getCollector()+".enable");
            if(enable != null) {
                enable.setSetValue(p.getEnable());
                p.setModified(date);
                propertiesRepository.save(enable);
            }

            ApmPropertySetting period = temp.get("collector."+p.getCollector()+".period");
            if(period != null) {
                period.setSetValue(p.getPeriod());
                p.setModified(date);
                propertiesRepository.save(period);
            }
        });
        propertiesRepository.saveAll(settings);
    }
}
